package com.ocean.web.util;

import com.google.common.collect.ImmutableList;
import ucar.ma2.Array;
import ucar.nc2.Dimension;
import ucar.nc2.Variable;
import ucar.nc2.dataset.NetcdfDataset;
import ucar.nc2.dataset.NetcdfDatasets;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Iterator;

/**
 * @ClassName NcimgUtil
 * @Description TODO
 * @Author houbing
 * @Date 2024/10/23 0023 14:18
 */
public class NcimgUtil {
    /**
     * 图片旋转180度
     * @param originalImage 参数：原始图片 类型：BufferedImage
     * @return
     */
    public static BufferedImage rotate180(BufferedImage originalImage) {
        // 创建一个旋转180度的AffineTransform对象
        AffineTransform transform = new AffineTransform();
        transform.rotate(Math.toRadians(180.0)); // 旋转180度
        transform.translate(-originalImage.getWidth(null), -originalImage.getHeight(null)); // 平移到中心

        // 创建AffineTransformOp对象，用于执行变换
        AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);

        // 执行旋转操作
        BufferedImage rotatedImage = op.filter(originalImage, null);

        return rotatedImage;
    }

    /**
     * 根据值获取深浅颜色 0-255
     * @param value 值
     * @param min  最小值
     * @param max  最大值
     * @return
     */
    public static Color getColor(double value, double min, double max) {
        double pjz = (min+max)/2;
        if (value < min) {
            if(value == -9999){//将-9999设置为白色
                return Color.WHITE;
            }else {
                return Color.BLUE; // 设置最小值的颜色
            }
        } else if (value > max) {
            return Color.RED; // 设置最大值的颜色
        } else {
            double ratio = (value - min) / (max - min); // 归一化到0.0到1.0之间
            if(value<(min/2)){
                return colorLerp(Color.BLUE, Color.green, ratio); // 在蓝色和红色之间进行线性插值
            }else if(value<pjz || value>(min/2)){
                return colorLerp(Color.green, Color.yellow, ratio); // 在蓝色和红色之间进行线性插值
            }else if(value>pjz || value < (max/2)){
                return colorLerp(Color.yellow, Color.ORANGE, ratio); // 在蓝色和红色之间进行线性插值
            }else{
                return colorLerp(Color.ORANGE, Color.RED, ratio); // 在蓝色和红色之间进行线性插值
            }


        }
    }

    /**
     * 去除空白区域
     */
    private static BufferedImage  delewhite(BufferedImage image){
        // 遍历像素，查找非白色的边界
        int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE;
        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                if (image.getRGB(x, y) != -1) { // 假设白色像素值为-1（白色）
                    minX = Math.min(minX, x);
                    minY = Math.min(minY, y);
                    maxX = Math.max(maxX, x);
                    maxY = Math.max(maxY, y);
                }
            }
        }

        // 计算非白色区域的宽度和高度
        int width = maxX - minX + 1;
        int height = maxY - minY + 1;
        // 创建一个新的图片，大小为非白色区域的大小
        BufferedImage croppedImage = image.getSubimage(minX, minY, width, height);
        return croppedImage;
    }

    /**
     * 线性插值颜色
     * @param c1 最小颜色
     * @param c2 最大颜色
     * @param ratio
     * @return
     */
    private static Color colorLerp(Color c1, Color c2, double ratio) {
        if (ratio > 1) {
            ratio = 1;
        }
        int red = (int) (c1.getRed() * (1 - ratio) + c2.getRed() * ratio);
        int green = (int) (c1.getGreen() * (1 - ratio) + c2.getGreen() * ratio);
        int blue = (int) (c1.getBlue() * (1 - ratio) + c2.getBlue() * ratio);
        return new Color(red, green, blue);
    }

    /**
     * 测试工具
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 打开 NetCDF 文件
        String filename = "E:\\55.nc";
        NetcdfDataset dataset = NetcdfDatasets.openDataset(filename);
        // 使用ImageIO获取所有GIF写入器
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("GIF");
        ImageWriter writer = writers.next();
        // 设置输出目标
        ImageOutputStream ios = ImageIO.createImageOutputStream(new File("E:\\image.gif"));
        writer.setOutput(ios);
        writer.prepareWriteSequence(null);

        // 假设数据变量名为 "data"
        Variable dataVar = dataset.findVariable("u");
        if (dataVar == null) {
            System.err.println("Data variable not found!");
            return;
        }

        // 获取数据的维度
        //int[] shape = dataVar.getShape();

        // 迭代时间维度（假设第一个维度是时间）
        //for (int t = 0; t < shape[0]; t++) {
            // 读取二维切片数据
            Array read = dataVar.slice(0, 0).read();
            int[] shape1 = read.getShape();
            float[][] slice = new float[shape1[shape1.length-2]][shape1[shape1.length-1]];
            for (int i = 0; i < shape1[shape1.length-2]; i++) {
                for (int j = 0; j < shape1[shape1.length-1]; j++) {
                    slice[i][j] = read.getFloat(i * shape1[shape1.length-1] + j);
                }
            }

            // 初始化最大值和最小值为数组中的第一个元素
            int max = 0;
            int min = 0;
            for (int i = 0; i < shape1[shape1.length-2]; i++) {
                for (int j = 0; j < shape1[shape1.length-1]; j++) {
                    int v = (int)slice[i][j];
                    if (v > max) {
                        max = v; // 更新最大值
                    }
                    if (v < min) {
                        if(v ==-9999){
                            //如果为-9999 不进行更改最小值
                        }else{
                            min = v; // 更新最小值
                        }

                    }
                }
            }
            // 生成图片
            BufferedImage image = new BufferedImage(shape1[shape1.length-1], shape1[shape1.length-2], BufferedImage.TYPE_INT_ARGB);
            for (int i = 0; i < shape1[shape1.length-2]; i++) {
                for (int j = 0; j < shape1[shape1.length-1]; j++) {
                    // 根据数据值设置颜色，这里是简单的灰度处理
                    int v = (int)slice[i][j];
                    Color color = null;

                    color = getColor(v, min, max); // 假设数值范围是0到100

                    //System.out.println(color);
                    image.setRGB(j, i, color.getRGB());
                }
            }
            Graphics2D g2d = image.createGraphics();
            g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), image.getWidth(), 0, 0, image.getHeight(), null);
            g2d.dispose();
            BufferedImage delewhite = delewhite(image);//去除图片白颜色
            BufferedImage bufferedImage = rotate180(delewhite);
            // 保存图片
             File outputFile = new File("E:\\image_" + 0 + ".png");
             ImageIO.write(bufferedImage, "png", outputFile);
            //IIOImage iioImage = new IIOImage(bufferedImage, null, null);
            //writer.writeToSequence(iioImage, null);

        //}
        System.out.println("图片生成成功！");
        // 关闭数据集
        dataset.close();
    }

}
